package com.aistar.service.impl;

import com.aistar.exception.SecKillException;
import com.aistar.mapper.ProductImagesMapper;
import com.aistar.mapper.ProductMapper;
import com.aistar.mapper.SeckillMapper;
import com.aistar.pojo.*;
import com.aistar.service.ProductImagesService;
import com.aistar.service.SeckillService;
import com.aistar.util.MessageUtil;
import com.aistar.util.ServerResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class SeckillServiceImpl implements SeckillService {

    @Autowired
    private SeckillMapper seckillMapper;

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductImagesService productImagesService;

    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public ServerResponse save(Seckill seckill) {
        return null;
    }

    @Override
    public ServerResponse modifyStatus(Seckill seckill) {
        return null;
    }

    @Override
    public ServerResponse modify(Seckill seckill) {
        return null;
    }

    @Override
    public ServerResponse getById(Integer id) {
        Seckill seckill = seckillMapper.selectByPrimaryKey(id);
        if (seckill!=null)
            return ServerResponse.getDataSuccess(seckill);
        return ServerResponse.getDataFailed(MessageUtil.NO_DATA);
    }

    @Override
    public ServerResponse getAll() {
        return null;
    }

    //@Cacheable声明式缓存的核心注解
    //第一次访问的时候将方法返回结果放入缓存
    //第二次访问时候不在执行内部的代码，而是从缓存中直接提取数据
    @Override
//    @Cacheable(value = "seckillProductVOList",key = "#seckillProductVO")
    public ServerResponse getproByTime(Date nowTime, Integer pageNum) {
        List<SeckillProductVO> seckillProductVOList = new ArrayList<>();
        //分页查询
        Page<Seckill> page = PageHelper.startPage(pageNum, 12);

        SeckillExample seckillExample = new SeckillExample();
        SeckillExample.Criteria criteria = seckillExample.createCriteria();

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MILLISECOND,0);
        Date time = calendar.getTime();

        criteria.andSeckillStartTimeLessThan(time);
        criteria.andSeckillEndTimeGreaterThan(time);
        List<Seckill> seckillList = seckillMapper.selectByExample(seckillExample);

        PageInfo pageInfo = page.toPageInfo();

        for (Seckill seckill : seckillList){
            Product product = productMapper.selectByPrimaryKey(seckill.getProductId());
            ServerResponse serverResponseImg = productImagesService.getByProductIdTo(seckill.getProductId());
            ProductImages productImages =  (ProductImages)serverResponseImg.getData();
            seckillProductVOList.add(new SeckillProductVO(seckill,product,productImages));
        }
        pageInfo.setList(seckillProductVOList);
        if (seckillProductVOList!=null&& seckillProductVOList.size()>0){
            return ServerResponse.getDataSuccess(pageInfo);
        }
       return ServerResponse.getDataFailed(MessageUtil.NO_DATA);

    }

    @Override
    public ServerResponse getCountBySeckill(Integer id) {
        Seckill seckill = seckillMapper.selectByPrimaryKey(id);
        if (seckill!=null){
            Integer count = seckill.getSeckillTotal();//库存
            Integer seckillId = seckill.getSeckillId();
            Integer proId = seckill.getProductId();
            Date seckillStartTime = seckill.getSeckillStartTime();
            Date seckillEndTime = seckill.getSeckillEndTime();
            Integer num = seckill.getSeckillNum();//卖出件数
            Double price = seckill.getSeckillPrice();

            if (count>0){
                System.out.println("恭喜你，秒杀成功");
                count = count -1;
                num = num + 1;
                Seckill seckill1 = new Seckill();
                seckill1.setProductId(proId);
                seckill1.setSeckillId(seckillId);
                seckill1.setSeckillStartTime(seckillStartTime);
                seckill1.setSeckillEndTime(seckillEndTime);
                seckill1.setSeckillNum(num);
                seckill1.setSeckillTotal(count);
                seckill1.setSeckillPrice(price);
                seckill1.setSeckillStatus(1);
                seckillMapper.updateByPrimaryKey(seckill1);
                return ServerResponse.getDataFailed("恭喜你，秒杀成功");
            }
            return ServerResponse.getDataFailed("抱歉！该商品已经没有了");
        }
        return ServerResponse.getDataFailed(MessageUtil.NO_DATA);

    }

    @Override
    public ServerResponse processSeckill(Integer seckillId, Integer userId, Integer num) throws SecKillException {
        Seckill seckill = seckillMapper.selectByPrimaryKey(seckillId);
        if (seckill==null){
            //没有秒杀活动了
            throw new SecKillException("秒杀活动不存在");
        }
        if (seckill.getSeckillStatus()==0){
            throw new SecKillException("秒杀活动还没开始");
        }else if (seckill.getSeckillStatus()==2){
            throw new SecKillException("秒杀活动已经结束");
        }
        Integer proId = (Integer)redisTemplate.opsForList().leftPop("secKill:count:"+seckill.getProductId());

        if (proId != null){
            //判断是否抢购过
            boolean isExiseted = redisTemplate.opsForSet().isMember("secKill:user:"+seckill.getSeckillId(),userId);
            if (!isExiseted){
                System.out.println("恭喜你抢购成功了，快去下单吧！");
                redisTemplate.opsForSet().add("secKill:user:"+seckill.getSeckillId(),userId);
            }else{
                redisTemplate.opsForList().rightPush("seckill:count:"+seckill.getSeckillId(),seckill.getProductId());
                throw new SecKillException("抱歉！您已经参加过此次活动，请勿重复参加！");
            }
        }else
            throw new SecKillException("抱歉! 该商品已经被抢光了");

return null;
    }


}
